/*  
     PlAr is Platform Arena: a 2D multiplayer shooting game
     Copyright (C) 2009 Ragagnin Antonio <spocchio@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package plar.core;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;

import plar.core.defaultActions.BasicMove;
import plar.core.defaultActions.Destroy;
import plar.core.defaultActions.LifeTimer;

/**
 * @author spocchio
 * 
 */
public class Element implements Runnable {

	public ActionManager actions;
	public boolean isRunnable;

	public Level level;
	public HashMap<String, Object> properties;
	public Parameters stdinfo;
	

	public Element() {

		actions = new ActionManager();
		properties = new HashMap<String, Object>();
		actions.addAction("basicMove", new BasicMove());
		setPosition(new Point(5, 5));
		setSpeed(new Point(0, 0));
		setSize(new Point(30, 30));
		setProperty("z", 0);

		setProperty("level", level);

		setProperty("type", "block");
		setStaticSprire("res/element.png");
		setProperty("canStop", true);
		setProperty("canCollide", false);
		setProperty("hasGravity", false);
		setProperty("friendlyList", new ArrayList<Element>());
		setProperty("isRunnable", false);
		stdinfo = new Parameters("me", this);
		stdinfo = stdinfo.put("subAction", "main");
		setProperty("isColliding", false);
		setProperty("isXColliding", false);
		setProperty("isYColliding", false);
		setProperty(".speed", new Point(0, 0));
		isRunnable = false;
		actions.addAction("destroy", new Destroy());
		actions.addAction("lifetimer", new LifeTimer());
		setProperty("lifeTime", -1);
	}

	public boolean canCollide(Point speed) {

		Rectangle r = getTraceRectangle(speed);

		return level.canCollide(r, this);

	}

	public ArrayList<Sprite> getCurrentSpriteSet() {
		return (ArrayList<Sprite>) getProperty("currentSpriteSet");
	}

	public Point getPosition() {
		return (Point) getProperty("position");
	}

	public Object getProperty(String s) {
		return properties.get(s);
	}

	public Rectangle getRectangle() {
		Rectangle r = new Rectangle(getPosition().x, getPosition().y,
				getSize().x, getSize().y);

		return r;
	}

	public Point getSize() {
		return (Point) getProperty("size");
	}

	public Point getSpeed() {
		return (Point) getProperty("speed");
	}

	public Rectangle getTraceRectangle(Point speed) {

		Rectangle r = new Rectangle(getPosition().x, getPosition().y,
				getSize().x + Math.abs(speed.x), getSize().y
						+ Math.abs(speed.y));

		if (speed.x < 0)
			r.x += speed.x;
		if (speed.y < 0)
			r.y += speed.y;
		return r;

	}

	public void run() {

		// moveMe();

		actions.runAll(stdinfo);
		// setProperty("collisionList",new ArrayList <Element> ());
	}

	public void setPosition(Point p) {
		setProperty("position", p);
	}

	public void setProperty(String s, Object o) {
		properties.put(s, o);
	}

	public void setSize(Point p) {
		setProperty("size", p);
	}

	public void setSpeed(Point p) {
		setProperty("speed", p);
	}

	public void setStaticSprire(String str) {
		Sprite s = new Sprite(str, -1);
		s.texturized = true;
		ArrayList<Sprite> ss = new ArrayList<Sprite>();
		ss.add(s);
		setProperty("currentSpriteSet", ss);
	}

	public boolean xcanCollide(int speed) {
		Rectangle r = new Rectangle(getPosition().x, getPosition().y,
				getSize().x + Math.abs(speed), getSize().y);

		if (speed < 0)
			r.x += speed;

		return level.canCollide(r, this);

	}

	public boolean ycanCollide(int speed) {
		Rectangle r = new Rectangle(getPosition().x, getPosition().y,
				getSize().x, getSize().y + Math.abs(speed));

		if (speed < 0)
			r.y += speed;
		return level.canCollide(r, this);

	}

}
